package com.redxiii.safesync.container;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.redxiii.safesync.Archive;
import com.redxiii.safesync.CryptoTool;

public class LocalContainer implements Container {

	private static final Logger logger = LoggerFactory.getLogger(LocalContainer.class);
	protected File rootFolder;
	protected Map<String,Archive> archives = new HashMap<String, Archive>();
	protected CryptoTool cryptoTool;
	
	@Override
	public void init(File rootFolder, CryptoTool cryptoTool) {
		this.rootFolder = rootFolder;
		this.cryptoTool = cryptoTool;
		this.fetch(rootFolder);
	}
	
	@Override
	public Map<String, Archive> getArchiveMap() {
		return archives;
	}
	
	protected void fetch(File rootDir) {
		
		for (File file : rootDir.listFiles()) {
			if (file.isHidden())
				continue;
			
			if (file.isDirectory()) {
				fetch(file);
			} else {
				addArchiveFile(file);
			}
		}
	}
	protected void addArchiveFile(File file) {
		Archive archive = new Archive(file, rootFolder);
		archives.put(archive.getAbsoluteName(), archive);
	}
	protected Map<String, Archive> loadArchiveMap() {
		fetch(rootFolder);
		
		return archives;
	}

	@Override
	public boolean update(Archive archive) {

		if (!archive.getFile().canRead()) {
			logger.warn("Could not read file {}", archive.getAbsoluteName());
			return false;
		}
		
		logger.debug("Updating {}", archive.getAbsoluteName());
		
		try {
			File newFile = new File(rootFolder.getAbsolutePath() + archive.getAbsoluteName());
			
			if (newFile.exists())
				newFile.delete();
			
			File fPath = new File(newFile.getParent());
			if (!fPath.exists())
				fPath.mkdirs();
			
			newFile.createNewFile();
			
			FileInputStream inputStream = new FileInputStream(archive.getFile());
			FileOutputStream outputStream = new FileOutputStream(newFile);
			
			cryptoTool.decrypt(inputStream, outputStream);
			
			Archive safeArchive = new Archive(newFile, rootFolder);
			archives.put(archive.getAbsoluteName(), safeArchive);
			
			return true;
		} catch (IOException e) {
			logger.error("Error updating file {}",archive.getName(),e);
		}
		
		return false;
	}

	@Override
	public boolean remove(Archive archive) {
		File fDeprecated = archive.getFile();
		archives.remove(archive.getAbsoluteName());
		return fDeprecated.delete();
	}
}
